<template>
  <div class="chao-map">
    <el-autocomplete
      v-model.trim="keyword"
      :fetch-suggestions="querySearch"
      :trigger-on-focus="false"
      highlight-first-item
      placeholder="请输入关键词获取地址"
      @select="handleSelect"
    />
    <div class="type-btn">
      <el-button type="primary" @click="addInteractions('Point')"
        >打点</el-button
      >
      <el-button type="primary" @click="addInteractions('Polygon')"
        >绘制围栏</el-button
      >
    </div>
    <div id="map" style="width: 100%; height: 600px"></div>
  </div>
</template>

<script setup name="ChaoMap">
import axios from 'axios';
import proj4 from 'proj4';
import { onMounted, ref } from 'vue';

const keyword = ref('');
const featureId = ref('');
const featureList = ref([]);
let olMap, draw, snap, source, selectSingleClick;

// 初始化
const initMap = () => {
  let originResult = {
    viewBounds: {
      top: 31.4105579601298,
      left: 117.927565298297,
      bottom: 28.1974421452528,
      leftBottom: {
        x: 117.927565298297,
        y: 28.1974421452528,
      },
      right: 121.140681113174,
      rightTop: {
        x: 121.140681113174,
        y: 31.4105579601298,
      },
    },
    viewer: {
      leftTop: {
        x: 0,
        y: 0,
      },
      top: 0,
      left: 0,
      bottom: 256,
      rightBottom: {
        x: 256,
        y: 256,
      },
      width: 256,
      right: 256,
      height: 256,
    },
    distanceUnit: 'METER',
    minVisibleTextSize: 0,
    coordUnit: 'DEGREE',
    scale: 1.8936724376996913e-7,
    description: 'none',
    paintBackground: false,
    maxVisibleTextSize: 0,
    maxVisibleVertex: 0,
    clipRegionEnabled: false,
    antialias: false,
    textOrientationFixed: false,
    angle: 0,
    prjCoordSys: {
      distanceUnit: 'METER',
      projectionParam: null,
      epsgCode: 4490,
      coordUnit: 'DEGREE',
      name: 'China Geodetic Coordinate System 2000',
      projection: null,
      type: 'PCS_EARTH_LONGITUDE_LATITUDE',
      coordSystem: {
        datum: {
          name: 'China 2000',
          type: 'DATUM_USER_DEFINED',
          spheroid: {
            flatten: 0.003352810681182319,
            name: 'CGCS2000',
            axis: 6378137,
            type: 'SPHEROID_USER_DEFINED',
          },
        },
        unit: 'DEGREE',
        spatialRefType: 'SPATIALREF_EARTH_LONGITUDE_LATITUDE',
        name: 'China Geodetic Coordinate System 2000',
        type: 'GCS_CHINA_2000',
        primeMeridian: {
          longitudeValue: 0,
          name: 'Greenwich',
          type: 'PRIMEMERIDIAN_GREENWICH',
        },
      },
    },
    minScale: 0,
    markerAngleFixed: false,
    overlapDisplayedOptions: null,
    visibleScales: [
      4.3219663656528633e-7, 8.64393273130568e-7, 1.728786546261142e-6,
      3.457573092522284e-6, 6.915146185044577e-6, 1.3830292370089154e-5,
      2.7660584740178342e-5, 5.5321169480356684e-5, 1.1064233896071337e-4,
      2.2128467792142674e-4, 4.4256935584285266e-4, 8.851387116857086e-4,
      0.0017702774233714106,
    ],
    dpi: 96,
    visibleScalesEnabled: true,
    customEntireBoundsEnabled: false,
    clipRegion: null,
    maxScale: 0,
    customParams: '',
    center: {
      x: 119.5341232057355,
      y: 29.8040000526913,
    },
    dynamicPrjCoordSyses: [
      {
        distanceUnit: 'METER',
        projectionParam: null,
        epsgCode: 4490,
        coordUnit: 'DEGREE',
        name: 'China Geodetic Coordinate System 2000',
        projection: null,
        type: 'PCS_EARTH_LONGITUDE_LATITUDE',
        coordSystem: {
          datum: {
            name: 'China 2000',
            type: 'DATUM_USER_DEFINED',
            spheroid: {
              flatten: 0.003352810681182319,
              name: 'CGCS2000',
              axis: 6378137,
              type: 'SPHEROID_USER_DEFINED',
            },
          },
          unit: 'DEGREE',
          spatialRefType: 'SPATIALREF_EARTH_LONGITUDE_LATITUDE',
          name: 'China Geodetic Coordinate System 2000',
          type: 'GCS_CHINA_2000',
          primeMeridian: {
            longitudeValue: 0,
            name: 'Greenwich',
            type: 'PRIMEMERIDIAN_GREENWICH',
          },
        },
      },
    ],
    colorMode: null,
    textAngleFixed: false,
    overlapDisplayed: false,
    userToken: {
      userID: '',
    },
    cacheEnabled: true,
    dynamicProjection: false,
    autoAvoidEffectEnabled: true,
    customEntireBounds: null,
    name: 'hzsyraster',
    bounds: {
      top: 30.9653841343798,
      left: 117.927565298297,
      bottom: 28.6426159710028,
      leftBottom: {
        x: 117.927565298297,
        y: 28.6426159710028,
      },
      right: 121.140681113174,
      rightTop: {
        x: 121.140681113174,
        y: 30.9653841343798,
      },
    },
    backgroundStyle: {
      fillGradientOffsetRatioX: 0,
      markerSize: 0,
      fillForeColor: {
        red: 255,
        green: 0,
        blue: 0,
        alpha: 255,
      },
      fillGradientOffsetRatioY: 0,
      markerWidth: 0,
      markerAngle: 0,
      fillSymbolID: 0,
      lineColor: {
        red: 0,
        green: 0,
        blue: 0,
        alpha: 255,
      },
      markerSymbolID: 0,
      lineWidth: 0.01,
      markerHeight: 0,
      fillOpaqueRate: 100,
      fillBackOpaque: false,
      fillBackColor: {
        red: 255,
        green: 255,
        blue: 255,
        alpha: 255,
      },
      fillGradientMode: 'NONE',
      lineSymbolID: 0,
      fillGradientAngle: 0,
    },
  };
  // const url = "https://iserver.supermap.io/iserver/services/map-changchun/rest/maps/长春市区图";
  const url =
    'http://t2.tianditu.gov.cn/img_w/wmts?' +
    'SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=img&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles' +
    '&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=5d638a4a95f764eceadcfbe938cc9455';
  // const url = "http://t0.tianditu.com/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=5d638a4a95f764eceadcfbe938cc9455";
  //#region  4490坐标系转换
  const tileGrid = ol.source.TileSuperMapRest.optionsFromMapJSON(
    url,
    originResult,
  ).tileGrid;
  const visableResolution = tileGrid.getResolutions();
  const projection = 'EPSG:4490';

  proj4.defs(projection, '+proj=longlat +ellps=GRS80 +no_defs');
  ol.proj.proj4 && ol.proj.proj4.register(proj4);
  let prj = ol.proj.get(projection);
  prj.setExtent([-180, -90, 180, 90]);
  const view = new ol.View({
    center: [120.07306101375532, 30.16428439369957],
    zoom: 10,
    projection: projection,
    resolutions: visableResolution,
  });
  //#endregion
  // 创建地图
  olMap = new ol.Map({
    // 设置地图图层
    target: 'map',
    controls: [],
    view: view,
  });

  // const imageMapLayer = new ol.layer.Tile({
  //   source: new ol.source.TileSuperMapRest({
  //     url: url,
  //     tileGrid: tileGrid,
  //     dpi: originResult.dpi,
  //   }),
  // });
  const imageMapLayer = new ol.layer.Tile({
    name: '天地图影像图层',
    source: new ol.source.XYZ({
      url: url,
      wrapX: false,
    }),
  });
  var TiandiMapCva = new ol.layer.Tile({
    name: '天地图矢量注记图层',
    source: new ol.source.XYZ({
      url: 'http://t0.tianditu.com/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=5d638a4a95f764eceadcfbe938cc9455',
      wrapX: false,
    }),
  });

  //#region 绘制图层
  source = new ol.source.Vector();
  const vector = new ol.layer.Vector({
    source: source,
    style: new ol.style.Style({
      fill: new ol.style.Fill({
        color: 'rgba(255, 255, 255, 0.2)',
      }),
      stroke: new ol.style.Stroke({
        color: '#ffcc33',
        width: 2,
      }),
    }),
  });
  //#endregion
  olMap.addLayer(imageMapLayer);
  olMap.addLayer(TiandiMapCva);
  olMap.addLayer(vector);
  // new ol.interaction.Select
  selectSingleClick = new ol.interaction.Select();
  olMap.addInteraction(selectSingleClick);
  selectSingleClick.on('select', (e) => {
    var features = e.target.getFeatures().getArray();
    if (features.length > 0 && features[0].$) {
      featureId.value = features[0].$;
      saveLonlat();
    }
  });
};

//清除绘制
const clearInteraction = () => {
  if (draw) {
    olMap.removeInteraction(draw);
  }
  if (snap) {
    olMap.removeInteraction(snap);
  }
};

// Point /点 Polygon/面
const addInteractions = (key) => {
  if (draw != undefined && draw != null) {
    olMap.removeInteraction(draw);
  }
  draw = new ol.interaction.Draw({
    source: source,
    type: key,
  });
  if (key == 'Polygon') {
    draw.on('drawend', async (e) => {
      const feature = new ol.Feature();
      feature.setGeometry(new ol.geom.Polygon(draw.Wv));
      feature.setStyle(
        new ol.style.Style({
          image: new ol.style.Circle({
            radius: 7,
            fill: new ol.style.Fill({
              color: 'red',
            }),
          }),
          stroke: new ol.style.Stroke({
            color: 'red',
            width: 2,
          }),
        }),
      );
      let uuId = await uuid();
      featureId.value = uuId;
      e.feature.setId(uuId);
      let data = {
        belongsType: key,
        color: 'red',
        id: uuId,
        lnglats: draw.Wv[0],
        type: 'Polygon',
        height: 75,
      };
      featureList.value.push(data);
      source.addFeature(feature);
      olMap.removeInteraction(draw);
    });
    olMap.addInteraction(draw);
  } else {
    draw.on('drawend', async (e) => {
      if (draw.Wv) {
        const feature = new ol.Feature();
        feature.setGeometry(new ol.geom.Point(draw.Wv));
        feature.setStyle(
          new ol.style.Style({
            image: new ol.style.Icon({
              anchor: [0.5, 1],
              src: '/static/images/jk-ico@2x.png',
            }),
          }),
        );
        let uuId = await uuid();
        featureId.value = uuId;
        feature.setId(uuId);
        let data = {
          belongsType: key,
          id: uuId,
          lnglat: draw.Wv,
          type: 'Point',
        };
        featureList.value.push(data);
        source.addFeature(feature);
        olMap.removeInteraction(draw);
      }
    });
    olMap.addInteraction(draw);
  }
};

// 获取点位信息
const saveLonlat = () => {
  let value = featureList.value.filter((J) => {
    return J.id == featureId.value;
  });
  console.log(value, featureId.value, '获取点位信息');
};

// 修改点位绑定的信息
// Object.assign(o1, o2, o3)
const recurrent = (data) => {
  featureList.value.forEach((element) => {
    if (element.id == featureId.value) {
      Object.assign(element, data);
    }
  });
  cancelSelect();
};

// 取消选中
const cancelSelect = () => {
  selectSingleClick.getFeatures().clear();
};

// 删除选择点位
const deleteActions = () => {
  try {
    if (featureId.value) {
      console.log(
        source.getFeatureById(featureId.value),
        featureId.value,
        '删除选择点位',
      );
      // source.removeFeature(source.getFeatureById(featureId.value));
      dialogVisible.value = false;
      let index = featureList.value.find((J) => J.id == featureId.value);
      featureList.value.splice(featureList.value.indexOf(index), 1);
      drawGraphics(featureList.value);
    }
  } catch (err) {
    console.log(err);
  }
};

const uuid = () => {
  var s = [];
  var hexDigits = '0123456789abcdef';
  for (var i = 0; i < 36; i++) {
    s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
  }
  s[14] = '4'; // bits 12-15 of the time_hi_and_version field to 0010
  s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01
  s[8] = s[13] = s[18] = s[23] = '-';

  var uuid = s.join('');
  return uuid;
};

const querySearch = (queryString, cb) => {
  axios
    .get('https://restapi.amap.com/v3/geocode/geo?parameters', {
      params: {
        key: '160e6c2523bfcce981b5cc34df5c26bb',
        address: queryString,
        // city: "hangzhou",
      },
    })
    .then((res) => {
      // console.log(res.data.geocodes);
      if (res.data.geocodes.length > 0) {
        let arr = [];
        res.data.geocodes.forEach((J) => {
          arr.push({
            value: J.formatted_address,
            center: J.location.split(','),
          });
        });
        cb(arr);
      } else {
        cb([]);
      }
    });
};

const handleSelect = (item) => {
  let center = item.center;
  olMap.getView().animate({
    center,
  });
};

const drawGraphics = (arr) => {
  source.clear();
  arr.forEach((J) => {
    if (J.lnglat) {
      drawPoint(J);
    } else {
      drawPolygon(J);
    }
  });
};

const drawPoint = (J) => {
  const feature = new ol.Feature();
  feature.setGeometry(new ol.geom.Point(J.lnglat));
  feature.setStyle(
    new ol.style.Style({
      image: new ol.style.Icon({
        anchor: [0.5, 1],
        src: '/static/images/jk-ico@2x.png',
      }),
    }),
  );
  feature.setId(J.id);
  source.addFeature(feature);
};

const drawPolygon = (J) => {
  var Polygon = new ol.Feature({
    geometry: new ol.geom.Polygon([J.lnglats]),
  });
  //设置区样式信息
  Polygon.setStyle(
    new ol.style.Style({
      //填充色
      fill: new ol.style.Fill({
        color: 'rgba(255, 255, 255, 0.5)',
      }),
      //边线颜色
      stroke: new ol.style.Stroke({
        color: J.color,
        width: 2,
      }),
      //形状
      image: new ol.style.Circle({
        radius: 7,
        fill: new ol.style.Fill({
          color: J.color,
        }),
      }),
    }),
  );
  Polygon.setId(J.id);
  source.addFeature(Polygon);
};

onMounted(() => {
  if (!olMap) {
    initMap();
  }
});
</script>

<style lang="scss" scoped>
.chao-map {
  position: relative;
}
.type-btn {
  position: absolute;
  top: 20px;
  left: 375px;
  z-index: 1000;
  & > ul {
    background: #fff;
    border-radius: 5px;
  }
}
.ol-viewport {
  position: absolute !important;
  height: 600px !important;
}
:deep(.el-autocomplete) {
  position: absolute !important;
  top: 20px;
  margin-left: 20px;
  z-index: 1000;
  width: 300px;
}
</style>
